/*=========================================================================================================
  * File Name	 : HLW8110.c
  * Describe 	 : HLW8110 UART 通讯程序,使用USATR2.(HLW8110 code,use USATE2),适用于HLW8112 UART通讯
  * Author	   : Tuqiang
  * Version	   : V1.6
  * Record	   : 2019/04/16，V1.2
  * Record	   : 2020/04/02, V1.3
	* Record	   : 2023/05/30, V1.5
	* Record	   : 2023/06/29, V1.6
==========================================================================================================*/
#include "HLW8110.h"
//#include "delay.h"
#include "stdio.h"
//#include "test.h"

#include "usart.h"
#include "stm32f0xx_usart.h"

#define HLW8110	 1

#if HLW8110

#define HIGH	1
#define LOW		0

//init函数初始化HLW8110的REG配置值
//#define	D_REG_SYSCON_DATA			0x0f04
//#define	D_REG_EMUCON_DATA			0x1003
//#define	D_REG_EMUCON2_DATA		0x0081

//init函数初始化HLW8110的REG配置值 直流
#define	D_REG_SYSCON_DATA			0x0f04
#define	D_REG_EMUCON_DATA			0x1173
#define	D_REG_EMUCON2_DATA		0x0fff

//K1--电流系数
//K2--电压系数
#define	D_K1	1
#define D_K2	1

//DELAY时间，根据UART的波特率进行调整
#define	D_2ms		2
#define	D_5ms		5
#define	D_7ms		7
#define	D_10ms	10
#define	D_15ms	15
#define	D_20ms	20

#define	D_DELAYTIME	D_10ms

//视在功率、功率因素、相角、瞬时功率只有一个REG，A通道或B通道只能二选一
#define D_CHANNEL_A		0
#define D_CHANNEL_B		1

typedef unsigned int u32;
typedef unsigned short int u16;
typedef unsigned char u8;

/*---------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------*/
union IntData
{
	u16  inte;
	u8 byte[2];
};
union LongData
{
    u32  word;
    u16  inte[2];
    u8   byte[4];
};
/*---------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------*/

unsigned char	u8_TxBuf[10];
unsigned char	u8_RxBuf[10];
unsigned char	u8_TX_Length;
unsigned char	u8_RX_Length;
unsigned char	u8_RX_Index;
//unsigned char	B_ReadReg_Time_EN;			// 串口读取寄存器数据，时间计数器标志位，1--开启计数，0--关闭计数
//unsigned char	B_Tx_Finish;
unsigned char	B_Rx_Finish;
unsigned char	B_Rx_Data_ING;						// 接收数据标志位	,		< 1:接收数据中,0:未接收到数据 >
unsigned char	B_Read_Error;							// UART读取出据校验和出错,< 1:数据读错，0:数据读取正确 >
//unsigned char	u8_ReadReg_Index;
//unsigned char	u8_ReadReg_Time;				// 串口读取寄存器数据的时间
/*---------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------*/

unsigned int    U16_TempData;

unsigned int    U16_IEData;
unsigned int    U16_IFData;
unsigned int    U16_RIFData;
unsigned int    U16_LineFData;
unsigned int    U16_AngleData;
unsigned int    U16_PFData;
unsigned int 		U16_HFConst_RegData;

unsigned int		U16_RmsPAOS;
unsigned int		U16_RmsPBOS;
unsigned int		U16_RmsIAOS;
unsigned int		U16_RmsIBOS;

/*---------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------*/
unsigned int	U16_RMSIAC_RegData; 			// A通道电流转换系数
unsigned int	U16_RMSIBC_RegData; 			// B通道电流转换系数
unsigned int	U16_RMSUC_RegData; 				// 电压通道转换系数
unsigned int	U16_PowerPAC_RegData; 		// A通道功率转换系数
unsigned int	U16_PowerPBC_RegData; 		// B通道功率转换系数
unsigned int	U16_PowerSC_RegData; 			// 视在功率转换系数,如果选择A通道，则是A通道视在功率转换系数。A和B通道只能二者选其一
unsigned int	U16_EnergyAC_RegData; 		// A通道有功电能(量)转换系数
unsigned int	U16_EnergyBC_RegData; 		// A通道有功电能(量)转换系数
unsigned int	U16_CheckSUM_RegData; 		// 转换系数的CheckSum
unsigned int	U16_CheckSUM_Data; 				// 转换系数计算出来的CheckSum

unsigned int	U16_Check_SysconReg_Data;
unsigned int	U16_Check_EmuconReg_Data;
unsigned int	U16_Check_Emucon2Reg_Data;

/*---------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------*/
unsigned long 	U32_RMSIA_RegData;			// A通道电流有效值寄存器
unsigned long 	U32_RMSU_RegData;				// 电压有效值寄存器
unsigned long 	U32_POWERPA_RegData;		// A通道功率有效值寄存器
unsigned long 	U32_ENERGY_PA_RegData;	// A通道有功电能（量）有效值寄存器

unsigned long 	U32_RMSIB_RegData;			// B通道电流有效值寄存器
unsigned long		U32_POWERPB_RegData;		// B通道功率有效值寄存器
unsigned long 	U32_ENERGY_PB_RegData;	// B通道有功电能（量）有效值寄存器

unsigned long 	U32_POWERPS_RegData;		// 视在功率有效值寄存器


unsigned long 	U32_TEMP_TC_RegData;		// 标定温度下的REG值
float   				F_TC;										// 标定温度TC
float   				F_Temperature;					// 当前温度

/*---------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------*/
float   F_AC_V;													// 电压有效值
float   F_AC_I_A;												// A通道电流
float   F_AC_P_A;												// A通道有功功率
float   F_AC_E_A;												// A通道有功电能(量)
float   F_AC_BACKUP_E_A;								// A通道电量备份
float   F_AC_PF;												// 功率因素，A通道和B通道只能选其一
float		F_Angle;												// 相角，A通道和B通道只能选其一

float   F_AC_I_B;												// B通道电流有效值
float   F_AC_P_B;												// B通道有功功率
float 	F_AC_E_B;												// B通道有功电能(量)
float   F_AC_BACKUP_E_B;								// B通道电量备份
float   F_AC_LINE_Freq;     						// 市电线性频率

float   F_AC_P_SC;											// 视在功率

unsigned char	U8_Channel;

DevPowerUseData str_DevPowerData;

/*---------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------*/

void delay_ms(u16 nms)
{
	HAL_Delay(nms);
}

/*=========================================================================================================
 * Function : void USART2_IRQHandler(void)
 * Describe : UART2串口中断，用于接收数据,9600bps,偶校验,even
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/16
==========================================================================================================*/
//void USART2_IRQHandler(void)
//{
//	//接收数据
//	if(USART2->SR&(1<<5))
//	{
//		if (u8_RX_Index < u8_RX_Length )
//		{
//			u8_RxBuf[u8_RX_Index] = USART2->DR;		// 数据接收中
//			u8_RX_Index++;
//
//			B_Rx_Data_ING = 1;										// 置数据接收标志位
//		}
//		else
//		{
//			B_Rx_Finish = TRUE;										// 数据接收完毕
//			u8_RX_Index = 0;
//
//		}
//	}
//
//	//发送数据
//}

//void USART4_IRQHandler(void)
//{
//	//接收数据
//	if(USART_GetITStatus(USART4, USART_IT_RXNE) != RESET)
//	{
//		if (u8_RX_Index < u8_RX_Length )
//		{
//			u8_RxBuf[u8_RX_Index] = USART_ReceiveData(USART4);
//			u8_RX_Index++;
//
//			B_Rx_Data_ING = 1;										// 置数据接收标志位
//		}
//		else
//		{
//			B_Rx_Finish = TRUE;										// 数据接收完毕
//			u8_RX_Index = 0;
//
//		}
//	}
//
//	//发送数据
//}

/*=========================================================================================================
 * Function : void Start_Send_UartData(unsigned char len)
 * Describe : UART2串口发送数据
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/16
=========================================================================================================*/
//void Start_Send_UartData(unsigned char len)
//{
//	unsigned char i;
//	for(i=0;i<len;i++)
//	{
//		while((USART2->SR&0X40) == 0);	//等待发送结束
//
//		//delay_us(10);									//两个字节之间增加延时
//		USART2->DR	=	u8_TxBuf[i];
//	}
//}

void Start_Send_UartData(unsigned char len)
{

//	unsigned char i;
//
//		for(i=0;i<len;i++)
//			 printf("%x ",u8_TxBuf[i]);
//		printf("uart4\r\n");
//	 HAL_UART_Transmit(&huart4, u8_TxBuf,len, 1000);
	 unsigned int i;
	for(i = 0; i < len; i++)
	{
		USART_SendData(USART4,u8_TxBuf[i]);
		while (USART_GetFlagStatus(USART4,USART_FLAG_TXE) == RESET);
	}
}
/*=========================================================================================================
 * Function : void Clear_RxBuf(void)
 * Describe : 在准备接收串口数据前，清空接收缓存器的数据
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
=========================================================================================================*/
void Clear_RxBuf(void)
{
	unsigned char i;
	for(i = 0;i<10;i++)
	{
		u8_RxBuf[i] = 0x00;
	}

	B_Rx_Data_ING = 0;
	B_Rx_Finish = FALSE;
	u8_RX_Index = 0;
}
/*=========================================================================================================
 * Function : unsigned char HLW8110_checkSum_Write(unsigned char u8_Reg_length)
 * Describe : 写REG 数据的CHECKSUM计算
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
=========================================================================================================*/
unsigned char HLW8110_checkSum_Write(unsigned char u8_Reg_length)
{
	unsigned char i;
	unsigned char Temp_u8_checksum;
	unsigned int	a;

	a = 0x0000;
	Temp_u8_checksum = 0;
	for (i = 0; i< (u8_Reg_length-1); i++)
		{
			a += u8_TxBuf[i];
		}

	a = ~a;
	Temp_u8_checksum = a & 0xff;

	return Temp_u8_checksum;
}
/*=========================================================================================================
 * Function : unsigned char HLW8110_checkSum_Read(void)
 * Describe : 读REG 数据的CHECKSUM计算
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
==========================================================================================================*/
unsigned char HLW8110_checkSum_Read(unsigned char u8_Reg_length)
{
	unsigned char i;
	unsigned char Temp_u8_checksum;
	unsigned int a;

	a = 0x0000;
	Temp_u8_checksum = 0;
	for (i = 0; i< (u8_Reg_length-1); i++)
		{
			a += u8_RxBuf[i];
		}

	a = a + u8_TxBuf[0] + u8_TxBuf[1];			//读REG的CHECKSUM计算，需要加上MCU向芯片发送的两个指令字节 A5 和 REG地址
	a = ~a;

	Temp_u8_checksum = a & 0xff;

//	printf("Temp_u8_checksum:%x u8_Reg_length:%x\r\n",Temp_u8_checksum,u8_Reg_length);
	return Temp_u8_checksum;

}
/*=========================================================================================================
 * Function : void Uart_HLW8110_WriteREG_EN(void)
 * Describe : 写使能,开启
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
==========================================================================================================*/
void Uart_HLW8110_WriteREG_EN(void)
{

	u8_TX_Length = 4;
	u8_RX_Length = 0;

	u8_TxBuf[0] = 0xa5;
	u8_TxBuf[1] = 0xea;
	u8_TxBuf[2] = 0xe5;
//	u8_TxBuf[3] = 0x8b;  //checksum
	u8_TxBuf[3] = HLW8110_checkSum_Write(u8_TX_Length);

	Start_Send_UartData(u8_TX_Length);

}
/*=========================================================================================================
 * Function : void Uart_HLW8110_WriteREG_DIS(void)
 * Describe : 写使能，关闭
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
==========================================================================================================*/
void Uart_HLW8110_WriteREG_DIS(void)
{

	u8_TX_Length = 4;
	u8_RX_Length = 0;

	u8_TxBuf[0] = 0xa5;
	u8_TxBuf[1] = 0xea;
	u8_TxBuf[2] = 0xdc;
//	u8_TxBuf[3] = 0x94;  //checksum
	u8_TxBuf[3] = HLW8110_checkSum_Write(u8_TX_Length);

	Start_Send_UartData(u8_TX_Length);
}

/*=========================================================================================================
 * Function : void Uart_HLW8110_Set_Channel_A(void)
 * Describe : 视在功率、功率因素、相角、瞬时功率只有一个REG，A通道或B通道只能二选一，此命令用于选择通道A测量视在功率和功率因素
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
==========================================================================================================*/
void Uart_HLW8110_Set_Channel_A(void)
{
	u8_TX_Length = 4;
	u8_RX_Length = 0;

	if (U8_Channel == D_CHANNEL_A)
	{
			u8_TxBuf[0] = 0xa5;
			u8_TxBuf[1] = 0xea;
			u8_TxBuf[2] = 0x5a;
	//	u8_TxBuf[3] = 0x16;  //checksum
			u8_TxBuf[3] = HLW8110_checkSum_Write(u8_TX_Length);
	}
	else
	{
			u8_TxBuf[0] = 0xa5;
			u8_TxBuf[1] = 0xea;
			u8_TxBuf[2] = 0xa5;
	//	u8_TxBuf[3] = 0xCB;  //checksum
			u8_TxBuf[3] = HLW8110_checkSum_Write(u8_TX_Length);
	}

	Start_Send_UartData(u8_TX_Length);
}

/*=========================================================================================================
 * Function : void Uart_Read_HLW8110_Reg(unsigned char ADDR_Reg,unsigned char u8_reg_length)
 * Describe : 读某个地址(ADDR_Reg)的REG数据
 * Input    :
 * Output   :
 * Return   :
 * Record   : 2019/04/04
==========================================================================================================*/
void Uart_Read_HLW8110_Reg(unsigned char ADDR_Reg,unsigned char u8_reg_length)
{
	u8_TxBuf[0] = 0xa5;
	u8_TxBuf[1] = ADDR_Reg;
	u8_TX_Length =  2;
	u8_RX_Length = u8_reg_length + 1;	// +1，是因为接收的数据长度，除了REG值，还有一个校验和数据


	Clear_RxBuf();										//清空接收缓冲区
	Start_Send_UartData(u8_TX_Length);
}
/*=========================================================================================================
 * Function : void Uart_Write_HLW8110_Reg(unsigned char ADDR_Reg,unsigned char u8_reg_length,unsigned long u32_data)
 * Describe : 写寄存器命令，u8_reg_length：写入的寄存器数据字节长度
 * Input    :
 * Output   :
 * Return   :
 * Record   : 2019/04/03
==========================================================================================================*/
void Uart_Write_HLW8110_Reg(unsigned char ADDR_Reg,unsigned char u8_reg_length,unsigned long u32_data)
{
	unsigned char i;
	union LongData Temp_u32_a;


	u8_TxBuf[0] = 0xa5;
	u8_TxBuf[1] = ADDR_Reg|0x80;											//写REG，地址RGE + 0x80,最高位赋1

	Temp_u32_a.word = u32_data;
	for (i = 0; i< u8_reg_length; i++)
		{
			u8_TxBuf[i+2] = Temp_u32_a.byte[u8_reg_length-1-i];						//STM32，32位MCU，union定义，是低位在前
			//u8_TxBuf[i+2] = Temp_u32_a.byte[4-u8_reg_length + i];				//STM8,STC MCU,   union定义，是高位在前
		}


	u8_TX_Length = 3 + u8_reg_length ;
	u8_RX_Length = 0;

	u8_TxBuf[u8_TX_Length-1] = HLW8110_checkSum_Write(u8_TX_Length);


	Start_Send_UartData(u8_TX_Length);
}

/*=========================================================================================================
 * Function : void Uart_HLW8110_Reset(void)
 * Describe : RESET command
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
==========================================================================================================*/
void Uart_HLW8110_Reset(void)
{

	u8_TX_Length = 4;
	u8_RX_Length = 0;

	u8_TxBuf[0] = 0xa5;
	u8_TxBuf[1] = 0xea;
	u8_TxBuf[2] = 0x96;
//	u8_TxBuf[3] = 0xda;  //checksum

	u8_TxBuf[3] = HLW8110_checkSum_Write(u8_TX_Length);

	Start_Send_UartData(u8_TX_Length);
}

/*=========================================================================================================
 * Function : void Judge_CheckSum_HLW8110_Calfactor(void)
 * Describe : 验证地址0x70-0x77地址的系数和
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/03/18
==========================================================================================================*/
unsigned char Judge_CheckSum_HLW8110_Calfactor(void)
{
	unsigned long a;
	//unsigned int b;
	//unsigned int c;
	unsigned char d;

  //读取RmsIAC、RmsIBC、RmsUC、PowerPAC、PowerPBC、PowerSC、EnergAc、EnergBc的值
  /*
  	IC出厂经过校准，每一颗IC的系数都是不同的，一般都在参考值附近，系数值参考如下，

  	RmsIAC			---		0xcad1
  	RmsIBC			---		0xcacf
  	RmsUC				---		0xa4c3
  	PowerPAC		---		0xab47
  	PowerPBC		---		0xab49
  	PowerSC			---		0xab41
  	EnergAc			---		0xe9cc
  	EnergBc			---		0xe9ce

  */

	Uart_Read_HLW8110_Reg(REG_RMS_IAC_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_RMSIAC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
		//	printf("A通道电流转换系数:%x\n " ,U16_RMSIAC_RegData);
	}


	Uart_Read_HLW8110_Reg(REG_RMS_IBC_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_RMSIBC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
	//	printf("B通道电流转换系数:%x\n " ,U16_RMSIBC_RegData);
	}


	Uart_Read_HLW8110_Reg(REG_RMS_UC_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_RMSUC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
	//	printf("电压通道转换系数:%x\n " ,U16_RMSUC_RegData);
	}

	Uart_Read_HLW8110_Reg(REG_POWER_PAC_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_PowerPAC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
	//	printf("A通道功率转换系数:%x\n " ,U16_PowerPAC_RegData);
	}

	Uart_Read_HLW8110_Reg(REG_POWER_PBC_ADDR,2);
		delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_PowerPBC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
	//	printf("B通道功率转换系数:%x\n " ,U16_PowerPAC_RegData);
	}

	Uart_Read_HLW8110_Reg(REG_POWER_SC_ADDR,2);
		delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_PowerSC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
	//	printf("视在功率转换系数:%x\n " ,U16_PowerSC_RegData);
	}

	Uart_Read_HLW8110_Reg(REG_ENERGY_AC_ADDR,2);
		delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_EnergyAC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
	//	printf("A通道电量转换系数:%x\n " ,U16_EnergyAC_RegData);

	}
	Uart_Read_HLW8110_Reg(REG_ENERGY_BC_ADDR,2);
		delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_EnergyBC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
	//	printf("B通道电量转换系数:%x\n " ,U16_EnergyBC_RegData);
	}


	Uart_Read_HLW8110_Reg(REG_CHECKSUM_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_CheckSUM_RegData= (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
	//	printf("系数校验和:%x\n " ,U16_CheckSUM_RegData);
	}


	a = 0;
  a = ~(0xffff+U16_RMSIAC_RegData + U16_RMSIBC_RegData + U16_RMSUC_RegData +
        U16_PowerPAC_RegData + U16_PowerPBC_RegData + U16_PowerSC_RegData +
          U16_EnergyAC_RegData + U16_EnergyBC_RegData  );

	U16_CheckSUM_Data = a & 0xffff;

	printf("计算系数校验和:%x\n " ,U16_CheckSUM_Data);


  d = 0;
	if ( U16_CheckSUM_Data == U16_CheckSUM_RegData)
	{
		d = 1;
		printf("校验和正确\r\n ");

	}
	else
	{
		d = 0;
		printf("校验和出错\r\n ");
	}

	return d;
}

/*=========================================================================================================
 * Function : void Check_WriteReg_Success(void)
 * Describe : 检验写入的REG是否正确写入,如果写入不正确，说明写入不成功，需要再次写入
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2020/04/02
==========================================================================================================*/
void Check_WriteReg_Success(void)
{
	B_Read_Error = 0;

	Uart_Read_HLW8110_Reg(REG_SYSCON_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_Check_SysconReg_Data =  (u8_RxBuf[0]<<8) + (u8_RxBuf[1]);
	}
	else
	{
		U16_Check_SysconReg_Data =  (u8_RxBuf[0]<<8) + (u8_RxBuf[1]);
		B_Read_Error = 1;
	}


	Uart_Read_HLW8110_Reg(REG_EMUCON_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_Check_EmuconReg_Data =  (u8_RxBuf[0]<<8) + (u8_RxBuf[1]);
	}
	else
	{
		U16_Check_EmuconReg_Data =  (u8_RxBuf[0]<<8) + (u8_RxBuf[1]);
		B_Read_Error = 1;
	}

	Uart_Read_HLW8110_Reg(REG_EMUCON2_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_Check_Emucon2Reg_Data =  (u8_RxBuf[0]<<8) + (u8_RxBuf[1]);
	}
	else
	{
		U16_Check_Emucon2Reg_Data =  (u8_RxBuf[0]<<8) + (u8_RxBuf[1]);
		B_Read_Error = 1;
	}

}
/*=========================================================================================================
 * Function : void Init_Temp_Channel_B(void)
 * Describe : B通道温度测量初始化
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2023/07/21
==========================================================================================================*/
void Init_Temp_Channel_B(void)
{
	unsigned long U32_D0;
	unsigned long U32_D1;
	unsigned long U32_D2;
	unsigned long U32_D3;

	Uart_HLW8110_WriteREG_EN();
	delay_ms(D_DELAYTIME);

	Uart_Write_HLW8110_Reg(REG_SYSCON_ADDR,2,(D_REG_SYSCON_DATA|0x0400)&0xFE3F);	//开启A通道，开启B通道，电压通道PGA = 1，电流通道PGA_A = 16,电流通道PGA_B = 1
	delay_ms(D_DELAYTIME);
	Uart_Write_HLW8110_Reg(REG_EMUCON_ADDR,2,D_REG_EMUCON_DATA|0x3040);						// 打开B通道温度测量功能，关闭B通道比较器功能,关闭B通道高通滤波器
	delay_ms(D_DELAYTIME);
	Uart_Write_HLW8110_Reg(REG_EMUCON2_ADDR,2,D_REG_EMUCON2_DATA&0xFF7F);					//开启B通道测量芯片内部温度,关闭B通道电流测量功能
	delay_ms(D_DELAYTIME);

	Uart_HLW8110_WriteREG_DIS();
	delay_ms(D_DELAYTIME);

	delay_ms(500);

// STEP1
	Uart_Read_HLW8110_Reg(REG_RMSIB_ADDR,3);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		//U32_RMSIB_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		U32_D0 = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		//printf("B通道电流寄存器:%lx\n " ,U32_RMSIB_RegData);
	}
	else
	{
	//	printf("B通道电流寄存器读取出错\r\n");
		B_Read_Error = 1;
	}

	Uart_Write_HLW8110_Reg(REG_EMUCON_ADDR,2,D_REG_EMUCON_DATA|0x3040|0x4000);						// STEP2
	delay_ms(D_DELAYTIME);
	delay_ms(500);
	Uart_Read_HLW8110_Reg(REG_RMSIB_ADDR,3);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		//U32_RMSIB_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		U32_D1 = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		//printf("B通道电流寄存器:%lx\n " ,U32_RMSIB_RegData);
	}
	else
	{
	//	printf("B通道电流寄存器读取出错\r\n");
		B_Read_Error = 1;
	}

	Uart_Write_HLW8110_Reg(REG_EMUCON_ADDR,2,D_REG_EMUCON_DATA|0x3040|0x8000);						// STEP3
	delay_ms(D_DELAYTIME);
	delay_ms(500);
	Uart_Read_HLW8110_Reg(REG_RMSIB_ADDR,3);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		//U32_RMSIB_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		U32_D2 = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		//printf("B通道电流寄存器:%lx\n " ,U32_RMSIB_RegData);
	}
	else
	{
	//	printf("B通道电流寄存器读取出错\r\n");
		B_Read_Error = 1;
	}


	Uart_Write_HLW8110_Reg(REG_EMUCON_ADDR,2,D_REG_EMUCON_DATA|0x3040|0xC000);						// STEP4
	delay_ms(D_DELAYTIME);
	delay_ms(500);
	Uart_Read_HLW8110_Reg(REG_RMSIB_ADDR,3);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		//U32_RMSIB_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		U32_D3 = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		//printf("B通道电流寄存器:%lx\n " ,U32_RMSIB_RegData);
	}
	else
	{
	//	printf("B通道电流寄存器读取出错\r\n");
		B_Read_Error = 1;
	}

	U32_TEMP_TC_RegData = (U32_D0+U32_D1+U32_D2+U32_D3)/4;
	F_TC = 28.0;		//标定温度28度



}


/*=========================================================================================================
 * Function : void Calculate_Temp_Channel_B(void)
 * Describe : 计算当前温度
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2023/07/21
==========================================================================================================*/
void Calculate_Temp_Channel_B(void)
{
	unsigned long a;
	Uart_Read_HLW8110_Reg(REG_RMSIB_ADDR,3);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		//U32_RMSIB_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		a = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		//printf("B通道电流寄存器:%lx\n " ,U32_RMSIB_RegData);

		F_Temperature = (F_TC+273.15)*a/U32_TEMP_TC_RegData -273.15;
	}
	else
	{
	//	printf("B通道电流寄存器读取出错\r\n");
		B_Read_Error = 1;
	}


}

/*=========================================================================================================
 * Function : void Init_HLW8110_REG(void)
 * Describe : init SYSCON REG / EMUCON REG / EMUCON2 REG,写入完成后，再读取是否写入成功
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2023/07/19
==========================================================================================================*/
void Init_HLW8110_REG(void)
{
	unsigned char i;


	for(i = 0;i<3;i++)
	{
		Uart_HLW8110_WriteREG_EN();
		delay_ms(D_DELAYTIME);

		//电流通道A设置命令，指定当前用于计算视在功率、功率因数、相角、瞬时有功功率、瞬时视在功率和有功功率过载的信号指示 的通道为通道A
		//	U8_Channel = D_CHANNEL_A;
		//	Uart_HLW8110_Set_Channel_A(D_CHANNEL_A);
		//	delay_ms(10);

		Uart_Write_HLW8110_Reg(REG_SYSCON_ADDR,2,D_REG_SYSCON_DATA);		//开启A通道，开启B通道，测温模块关闭，比较功能关闭，电压通道PGA = 1，电流通道PGA_A = 16,电流通道PGA_B = 16
		delay_ms(D_DELAYTIME);
		Uart_Write_HLW8110_Reg(REG_EMUCON_ADDR,2,D_REG_EMUCON_DATA);		// 打开B通道电流测量功能
		delay_ms(D_DELAYTIME);
		Uart_Write_HLW8110_Reg(REG_EMUCON2_ADDR,2,D_REG_EMUCON2_DATA);	//DataRate = 3.4Hz
		delay_ms(D_DELAYTIME);

		Uart_HLW8110_WriteREG_DIS();
		delay_ms(D_DELAYTIME);

		B_Read_Error = 0;
		Check_WriteReg_Success();
		if (B_Read_Error == 1)		// 写入REG不成功，需重新写入
		{
				i++;			//重新写入
				delay_ms(200);
		}
		else
		{
				i = 6;			//跳出3次循环
		}
	}

}

/*=========================================================================================================
 * Function : void Init_HLW8110_OFFSET(void)
 * Describe : OFFSET校准，对OFFSET有要求的项目，可以填加此函数,此代码放在出厂校准里，短路或悬空电流信号，不能加负载
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2023/08/09
==========================================================================================================*/
void Init_HLW8110_OFFSET(void)
{
	unsigned char i;
	unsigned long a;
	unsigned long b;
	unsigned long c;
	//短路电流信号
	//对RMSIA

	a = 0;
	b = 0;
	c = 0;
	for (i = 0;i<12;i++)
	{
		Uart_Read_HLW8110_Reg(REG_RMSIA_ADDR,3);
		delay_ms(D_DELAYTIME);
		if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
		{
			U32_RMSIA_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		//	printf("A通道电流寄存器:%lx\n " ,U32_RMSIA_RegData);
		}
		else
		{
		//	printf("A通道电流寄存器读取出错\r\n");
			B_Read_Error = 1;
		}


		if (i>3)
		{
			a	+=	U32_RMSIA_RegData;
		}


		delay_ms(300);//3.4HZ
		//delay_ms(40);//27HZ
	}


	a = a/8;
	if (a>0x800000)
	{
		b = 0xFFFFFF-a ;
		b = b+1;
	}
	else
	{
		b = 0xFFFFFF-a ;
	}

	//b:bit23-bit0,取b.bit23 == c.bit15, b.bit14-bit0 == c.bit14-bit0

	if ((b&0x800000) == 0x800000)		//最高位是1
	{
		c = (b&0x00FFFF);
		c = (c|0x8000);		//最高位符号位
	}
	else
	{
		c = (b&0x00FFFF);
		c = (c&0x7FFF);
	}

	Uart_HLW8110_WriteREG_EN();
	delay_ms(D_DELAYTIME);

	Uart_Write_HLW8110_Reg(REG_RmsIAOS_ADDR,2,c);	//开启A通道，开启B通道，测温模块关闭，比较功能关闭，电压通道PGA = 1，电流通道PGA = 16
	delay_ms(D_DELAYTIME);


	Uart_HLW8110_WriteREG_DIS();

}

/*=========================================================================================================
 * Function : void Init_HLW8110(void)
 * Describe :
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
==========================================================================================================*/
void Init_HLW8110(void)
{
	unsigned char d;


	Init_HLW8110_REG();

	//Init_Temp_Channel_B();
	//Calculate_Temp_Channel_B();

	//Init_HLW81+10_OFFSET();

	//delay_ms(D_DELAYTIME);
  //读取地址是0x6F至0x77的寄存器，验证系数是否正确

  d = Judge_CheckSum_HLW8110_Calfactor();
  if (d == 0)		//校验系数读取失败，使用默认系数，但准确度会稍差，或者再次读取数据
  {
  	//读取失败，使用默认系数值
		U16_RMSIAC_RegData		=	0xcad1;
		U16_RMSIBC_RegData		=	0xcacf;
		U16_RMSUC_RegData			=	0xa4c3;
		U16_PowerPAC_RegData	=	0xab47;
		U16_PowerPBC_RegData	=	0xab49;
		U16_PowerSC_RegData		=	0xab41;
		U16_EnergyAC_RegData	=	0xe9cc;
		U16_EnergyBC_RegData	=	0xe9ce;
  }



}




/*=========================================================================================================
 * Function : void Check_REGDATA_HLW8110(void)
 * Describe : 为提高软件可靠性，在程序运行过程中，检验初始化是否成功，或是因浪涌等原因，REG数据丢失，需要重新初始化
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2023/06/14
==========================================================================================================*/
void Check_REGDATA_HLW8110(void)
{
	unsigned char B_InitIC_Error;

	//读取00 01 13地址REG
	Check_WriteReg_Success();

	if ((U16_Check_SysconReg_Data == D_REG_SYSCON_DATA) && (U16_Check_EmuconReg_Data == D_REG_EMUCON_DATA) && (U16_Check_Emucon2Reg_Data == D_REG_EMUCON2_DATA) )
	{
			B_InitIC_Error = 0;
	}
	else
	{
			B_InitIC_Error = 1;
	}

	//	B_InitIC_Error = 0;			//REG 初始化OK
	//	B_InitIC_Error = 1;			//REG 配置数据异常,有可能是上电init芯片没有成功，或是因为浪涌等原因，掉电复位
	if (B_InitIC_Error == 1)		//B_InitIC_Error = 1，表示芯片内部REG_EMUCON的值发生了变化，恢复成默认值，或是更改成其它值
	{
		printf("SYSCON、EMUCON、EMUCON2地址的REG数据与配置值不同，需重新初始化\r\n");

		//初始化操作
		//也可以在这里设置一个循环，初始化成功后，再跳出
		//默认配置，不初始化，可以读取电压、电压、功率，不能读取电量(默认配置未开启)
		Init_HLW8110();

	}




}

/*=========================================================================================================
 * Function : void Read_HLW8112_IA(void)
 * Describe : 读取A通道电流
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
==========================================================================================================*/
void Read_HLW8110_IA(void)
{
	float a;

	Uart_Read_HLW8110_Reg(REG_RMSIA_ADDR,3);
	delay_ms(D_DELAYTIME);
//	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U32_RMSIA_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
//		printf("A通道电流寄存器:%lx\n " ,U32_RMSIA_RegData);
	}
	else
	{
//		printf("A通道电流寄存器读取出错\r\n");
		B_Read_Error = 1;
	}


	//A通道电流PGA = 16,电压通道PGA = 1;电流采样电阻1mR,电压采样电阻1M
  //计算公式,U16_AC_I = (U32_RMSIA_RegData * U16_RMSIAC_RegData)/(电流系数* 2^23）
	if ((U32_RMSIA_RegData & 0x800000) == 0x800000)
	 {
			F_AC_I_A = 0;
	 }
	 else
	 {
		a = (float)U32_RMSIA_RegData;
		a = a * U16_RMSIAC_RegData;
		a = a/0x800000;                     	//	电流计算出来的浮点数单位是mA,比如5003.12
   	a = a/D_K1;  													// D_K1 = 电流系数
		a = a/1000;              						 	//	a= 5003ma,a/1000 = 5.003A,单位转换成A
		a = a * D_CAL_A_I;									 	//	D_CAL_A_I是校正系数，默认是1
		F_AC_I_A = a;
	 }
}

/*=========================================================================================================
 * Function : void Read_HLW8112_IA(void)
 * Describe : 读取B通道电流
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
==========================================================================================================*/
void Read_HLW8110_IB(void)
{
	float a;

	Uart_Read_HLW8110_Reg(REG_RMSIB_ADDR,3);
		delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U32_RMSIB_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		//printf("B通道电流寄存器:%lx\n " ,U32_RMSIB_RegData);
	}
	else
	{
	//	printf("B通道电流寄存器读取出错\r\n");
		B_Read_Error = 1;
	}


	//B通道电流PGA = 16,电压通道PGA = 1;电流采样电阻1mR,电压采样电阻1M
  //计算公式,U16_AC_B = (U32_RMSIB_RegData * U16_RMSIBC_RegData)/(电流系数* 2^23）
	if ((U32_RMSIB_RegData & 0x800000) == 0x800000)
	 {
			F_AC_I_B = 0;
	 }
	 else
	 {
		a = (float)U32_RMSIB_RegData;
		a = a * U16_RMSIBC_RegData;
		a  = a/0x800000;                     //	电流计算出来的浮点数单位是mA,比如5003.12
   	a = a/D_K1;  										// D_K1 = 电流系数
		a = a/1000;              						//	a= 5003ma,a/1000 = 5.003A,单位转换成A
		a = a * D_CAL_B_I;									//	D_CAL_A_I是校正系数，默认是1
		F_AC_I_B = a;
	 }
}
/*=========================================================================================================
 * Function : void Read_HLW8110_U(void)
 * Describe : 读取电压
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
==========================================================================================================*/
void Read_HLW8110_U(void)
{
	float a;

	Uart_Read_HLW8110_Reg(REG_RMSU_ADDR,3);
		delay_ms(D_DELAYTIME);
//		delay_ms(D_DELAYTIME);
//		printf("%x %x %x %x\r\n " ,u8_RxBuf[0],u8_RxBuf[1],u8_RxBuf[2],u8_RxBuf[3]);
	if (u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U32_RMSU_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
//		printf("电压通道寄存器:%lx\n " ,U32_RMSU_RegData);
	}
	else
	{
		U32_RMSU_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
//		printf("电压通道寄存器:%lx\r\n " ,U32_RMSU_RegData);
//		printf("电压通道寄存器读取出错\r\n");
		B_Read_Error = 1;
	}

		//电压
		//计算:U16_AC_V = (U32_RMSU_RegData * U16_RMSUC_RegData)/2^23

	 if ((U32_RMSU_RegData &0x800000) == 0x800000)
	 {
			F_AC_V = 0;
	 }
  else
	{
  	a =  (float)U32_RMSU_RegData;
  	a = a*U16_RMSUC_RegData;
  	a = a/0x400000;
   	a = a/D_K2;  										// D_K2 = 电压系数
  	a = a/100;    						//	计算出a = 22083.12mV,a/100表示220.8312V，电压转换成V
  	a = a*D_CAL_U;						//	D_CAL_U是校正系数，默认是1,
  	F_AC_V = a;
	}
}
/*=========================================================================================================
 * Function : void Read_HLW8110_PA(void)
 * Describe : 读取A通道功率
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
==========================================================================================================*/
void Read_HLW8110_PA(void)
{
	float a;
	float b;

	Uart_Read_HLW8110_Reg(REG_POWER_PA_ADDR,4);
		delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U32_POWERPA_RegData = (unsigned long)(u8_RxBuf[0]<<24) + (unsigned long)(u8_RxBuf[1]<<16) + (unsigned long)(u8_RxBuf[2]<<8) + (unsigned long)(u8_RxBuf[3]);
//		printf("A通道功率寄存器:%lx\n " ,U32_POWERPA_RegData);
	}
	else
	{
//		printf("A通道功率寄存器读取出错\r\n");
		B_Read_Error = 1;
	}


	 if (U32_POWERPA_RegData > 0x80000000)
   {
     b = ~U32_POWERPA_RegData;
     a = (float)b;
   }
   else
     a =  (float)U32_POWERPA_RegData;


	//功率需要分正功和负功
  //计算,U16_AC_P = (U32_POWERPA_RegData * U16_PowerPAC_RegData)/(2^31*电压系数*电流系数)
	//单位为W,比如算出来5000.123，表示5000.123W

   a = a*U16_PowerPAC_RegData;
   a = a/0x80000000;
   a = a/D_K1;  										// D_K1 = 电流系数
   a = a/D_K2;  										// D_K2 = 电压系数
   a = a * D_CAL_A_P;						//	D_CAL_A_P是校正系数，默认是1
   F_AC_P_A = a;										//	单位为W,比如算出来5000.123，表示5000.123W

}



/*=========================================================================================================
 * Function : void Read_HLW8110_PSC(void)
 * Describe : 视在功率
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2023/05/30
==========================================================================================================*/
void Read_HLW8110_PSC(void)
{
	float a;
	float b;

	Uart_Read_HLW8110_Reg(REG_POWER_PS_ADDR,4);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U32_POWERPS_RegData = (unsigned long)(u8_RxBuf[0]<<24) + (unsigned long)(u8_RxBuf[1]<<16) + (unsigned long)(u8_RxBuf[2]<<8) + (unsigned long)(u8_RxBuf[3]);
		//printf("A通道功率寄存器:%lx\n " ,U32_POWERPA_RegData);
	}
	else
	{
		//printf("A通道功率寄存器读取出错\r\n");
		B_Read_Error = 1;
	}


	 if (U32_POWERPS_RegData > 0x80000000)
   {
     b = ~U32_POWERPS_RegData;
     a = (float)b;
   }
   else
     a =  (float)U32_POWERPS_RegData;


	//功率需要分正功和负功
  //计算,F_AC_P_SC = (U32_POWERPS_RegData * U16_PowerSC_RegData)/(2^31*电压系数*电流系数)
	//单位为W,比如算出来5000.123，表示5000.123W

    a = a*U16_PowerSC_RegData;
    a = a/0x80000000;
   	a = a/D_K1;  										// D_K1 = 电流系数
   	a = a/D_K2;  										// D_K2 = 电压系数
    a = a * D_CAL_A_P;						//	D_CAL_A_P是校正系数，默认是1
    F_AC_P_SC = a;								//	单位为W,比如算出来5000.123，表示5000.123W

}

/*=========================================================================================================
 * Function : void Read_HLW8110_PB(void)
 * Describe : 读取B通道功率
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
==========================================================================================================*/
void Read_HLW8110_PB(void)
{
	float a;
	float b;

	Uart_Read_HLW8110_Reg(REG_POWER_PB_ADDR,4);
		delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U32_POWERPB_RegData = (unsigned long)(u8_RxBuf[0]<<24) + (unsigned long)(u8_RxBuf[1]<<16) + (unsigned long)(u8_RxBuf[2]<<8) + (unsigned long)(u8_RxBuf[3]);
		//printf("B通道功率寄存器:%lx\n " ,U32_POWERPB_RegData);
	}
	else
	{
	//	printf("B通道功率寄存器读取出错\r\n");
		B_Read_Error = 1;
	}


	 if (U32_POWERPB_RegData > 0x80000000)
   {
     b = ~U32_POWERPB_RegData;
     a = (float)b;
   }
   else
     a =  (float)U32_POWERPB_RegData;


	//功率需要分正功和负功
  //计算,U16_AC_P = (U32_POWERPA_RegData * U16_PowerPAC_RegData)/(2^31*电压系数*电流系数)
	//单位为W,比如算出来5000.123，表示5000.123W

    a = a*U16_PowerPBC_RegData;
    a = a/0x80000000;
   a = a/D_K1;  										// D_K1 = 电流系数
   a = a/D_K2;  										// D_K2 = 电压系数
    a = a * D_CAL_B_P;						//D_CAL_A_P是校正系数，默认是1
    F_AC_P_B = a;									//单位为W,比如算出来5000.123，表示5000.123W

}




/*=========================================================================================================
 * Function : void void Read_HLW8112_EA(void)
 * Describe : 读取A通道有功电量
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
==========================================================================================================*/
void Read_HLW8110_EA(void)
{
	float a;
	Uart_Read_HLW8110_Reg(REG_ENERGY_PA_ADDR,3);
	delay_ms(D_DELAYTIME);

	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U32_ENERGY_PA_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		//printf("A通道有功电量寄存器:%lx\n " ,U32_ENERGY_PA_RegData);
	}
	else
	{
		//printf("A通道有功电量寄存器读取出错\r\n");
		B_Read_Error = 1;
	}

	Uart_Read_HLW8110_Reg(REG_HFCONST_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_HFConst_RegData = (unsigned int)(u8_RxBuf[0]<<8) + (unsigned int)(u8_RxBuf[1]);
		//printf("HFCONST常数 = :%d\n " ,U16_HFConst_RegData);
	}
	else
	{
		//printf("HFCONST常数寄存器读取出错\r\n");
		B_Read_Error = 1;
	}

	//电量计算,电量 = (U32_ENERGY_PA_RegData * U16_EnergyAC_RegData * HFCONST) /(K1*K2 * 2^29 * 4096)
	//HFCONST:默认值是0x1000, HFCONST/(2^29 * 4096) = 0x20000000
	a =  (float)U32_ENERGY_PA_RegData;
  a = a*U16_EnergyAC_RegData;
  a = a/0x20000000;             //电量单位是0.001KWH,比如算出来是2.002,表示2.002KWH
   a = a/D_K1;  										// D_K1 = 电流系数
   a = a/D_K2;  										// D_K2 = 电压系数
   a = a * D_CAL_A_E;     			//D_CAL_A_E是校正系数，默认是1
  F_AC_E_A = a;
	F_AC_BACKUP_E_A = F_AC_E_A;

}

/*=========================================================================================================
 * Function : void void Read_HLW8112_EB(void)
 * Describe : 读取B通道有功电量
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/03
==========================================================================================================*/

void Read_HLW8110_EB(void)
{
	float a;
	Uart_Read_HLW8110_Reg(REG_ENERGY_PB_ADDR,3);
	delay_ms(D_DELAYTIME);

	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U32_ENERGY_PB_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		//printf("B通道有功电量寄存器:%lx\n " ,U32_ENERGY_PB_RegData);
	}
	else
	{

//printf("B通道有功电量寄存器读取出错\r\n");
		B_Read_Error = 1;
	}

	Uart_Read_HLW8110_Reg(REG_HFCONST_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		U16_HFConst_RegData = (unsigned int)(u8_RxBuf[0]<<8) + (unsigned int)(u8_RxBuf[1]);
		//printf("HFCONST常数 = :%d\n " ,U16_HFConst_RegData);
	}
	else
	{
		//printf("HFCONST常数寄存器读取出错\r\n");
		B_Read_Error = 1;
	}

	//电量计算,电量 = (U32_ENERGY_PA_RegData * U16_EnergyAC_RegData * HFCONST) /(K1*K2 * 2^29 * 4096)
	//HFCONST:默认值是0x1000, HFCONST/(2^29 * 4096) = 0x20000000
	a =  (float)U32_ENERGY_PB_RegData;
  a = a*U16_EnergyBC_RegData;
  a = a/0x20000000;             //电量单位是0.001KWH,比如算出来是2.002,表示2.002KWH
   a = a/D_K1;  										// D_K1 = 电流系数
   a = a/D_K2;  										// D_K2 = 电压系数
   a = a * D_CAL_B_E;     			//D_CAL_A_E是校正系数，默认是1
  F_AC_E_B = a;
	F_AC_BACKUP_E_B = F_AC_E_B;

}

/*=========================================================================================================
 * Function : void Read_HLW8110_LineFreq(void)
 * Describe : 读取A通道的线性频率，因为8110无外置晶振，可以上电进行频率校准
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/12
==========================================================================================================*/
void Read_HLW8110_LineFreq(void)
{
	float a;
	unsigned long b;
	Uart_Read_HLW8110_Reg(REG_UFREQ_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		b = (unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);
		//printf("A通道线性频率寄存器:%ld\n " ,b);
	}
	else
	{
		//printf("A通道线性频率寄存器读取出错\r\n");
		B_Read_Error = 1;
	}
	a = (float)b;
	a = 3579545/(8*a);

	a	=	a*1;			//1是系数，如果不准，可以在第一次上电时进行校准

	F_AC_LINE_Freq = a;
}

/*=========================================================================================================
 * Function : void Read_HLW8110_PF(void)
 * Describe : 读取功率因素
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/03/18
==========================================================================================================*/
void Read_HLW8110_PF(void)
{
  float a;
  unsigned long b;

//测量A通道的功率因素，需要发送EA+5A命令
//测量B通道的功率因素，需要发送EA+A5命令

	Uart_Read_HLW8110_Reg(REG_PF_ADDR,3);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		b = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
		//printf("A通道功率因素寄存器:%ld\n " ,b);
	}
	else
	{
		//printf("读取A通道功率因素寄存器出错\r\n");
		B_Read_Error = 1;
	}

  if (b>0x800000)       //为负，容性负载
  {
      a = (float)(0xffffff-b + 1)/0x7fffff;
  }
  else
  {
      a = (float)b/0x7fffff;
  }

  if (F_AC_P_A < 0.3) // 小于0.3W，空载或小功率，PF不准，置0处理
	  a = 0;

  F_AC_PF = a;

}

/*=========================================================================================================
 * Function : void Read_HLW8110_Angle(void)
 * Describe : 读取相位角
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2019/04/12
==========================================================================================================*/
void Read_HLW8110_Angle(void)
{
	float a;
	unsigned long b;
	Uart_Read_HLW8110_Reg(REG_ANGLE_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		b =(unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);
		printf("A通道线相角寄存器:%ld\n " ,b);
	}
	else
	{
		printf("A通道线相角寄存器出错\r\n");
		B_Read_Error = 1;
	}

	if ( F_AC_PF < 55)	//线性频率50HZ
	{
		a = b;
		a = a * 0.0805;
		F_Angle = a;
	}
	else
	{
		//线性频率60HZ
		a = b;
		a = a * 0.0965;
		F_Angle = a;
	}


	if (F_AC_P_A < 0.5)		//功率小于0.5时，说明没有负载，相角为0
	{
		F_Angle = 0;
	}

	if (F_Angle < 90)
	{
		a = F_Angle;
		printf("电流超前电压:%f\n " ,a);
	}
	else if (F_Angle < 180)
	{
		a = 180-F_Angle;
		printf("电流滞后电压:%f\n " ,a);
	}
	else if (F_Angle < 360)
	{
		a = 360 - F_Angle;
		printf("电流滞后电压:%f\n " ,a);
	}
	else
	{
			a = F_Angle -360;
			printf("电流超前电压:%f\n " ,a);
	}
}
//////////////////////////////////////////////////////////////////////////
void Read_HLW8110_REG(void)
{

	unsigned long b;
//IE
	Uart_Read_HLW8110_Reg(REG_IE_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		b =(unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);
		U16_IEData = b;
	}
	else
	{
		B_Read_Error = 1;
	}
//IF
	Uart_Read_HLW8110_Reg(REG_IF_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		b =(unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);
		U16_IFData = b;
	}
	else
	{
		B_Read_Error = 1;
	}
//RIF
		Uart_Read_HLW8110_Reg(REG_RIF_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		b =(unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);
		//printf("A通道线相角寄存器:%ld\n " ,b);
		U16_RIFData = b;
	}
	else
	{
		B_Read_Error = 1;
	}
//RmsPAOS
	Uart_Read_HLW8110_Reg(REG_RmsPAOS_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		b =(unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);
		U16_RmsPAOS = b;
	}
	else
	{
		B_Read_Error = 1;
	}

/*
//RmsPBOS
	Uart_Read_HLW8110_Reg(REG_RmsPBOS_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		b =(unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);
		U16_RmsPBOS = b;
	}
	else
	{
		B_Read_Error = 1;
	}
//RmsIAOS
	Uart_Read_HLW8110_Reg(REG_RmsIAOS_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		b =(unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);
		U16_RmsIAOS = b;
	}
	else
	{
		B_Read_Error = 1;
	}

//RmsIBOS
	Uart_Read_HLW8110_Reg(REG_RmsIBOS_ADDR,2);
	delay_ms(D_DELAYTIME);
	if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
	{
		b =(unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);
		U16_RmsIBOS = b;
	}
	else
	{
		B_Read_Error = 1;
	}
*/
}




void Read_HLW8110_Data(void)
{
	Read_HLW8110_U();
	Read_HLW8110_IA();
	Read_HLW8110_PA();
	Read_HLW8110_EA();

	str_DevPowerData.DevVoltage = F_AC_V;
	str_DevPowerData.DevCurrentFlow = F_AC_I_A*100;
	str_DevPowerData.DevCurrentPower = F_AC_P_A;
	str_DevPowerData.DevQuantityElect = F_AC_E_A;

//	printf(" F_AC_V = %.2f	V	\r\n " ,F_AC_V);						//	电压
	printf(" F_AC_I_A = %.3f	A	\r\n" ,F_AC_I_A);						//	A通道电流
	printf(" DevCurrentFlow = %d 0mA	\r\n" ,str_DevPowerData.DevCurrentFlow);
	//	printf(" F_AC_P_A = %.2f	W	\r\n" ,F_AC_P_A);						//	A通道功率
////	printf(" F_AC_P_SC = %.2f	W	\r\n " ,F_AC_P_SC);				//	视在功率
//	printf(" F_AC_E_A = %f	KWH	\r\n " ,F_AC_E_A);				//	A通道电量
//	printf("\r\n");//插入换行
}


void Read_HLW8110_Test(void)
{
	Read_HLW8110_U();
	Read_HLW8110_IA();
	Read_HLW8110_PA();
	Read_HLW8110_EA();

	printf(" F_AC_V = %.2f	V	\r\n " ,F_AC_V);						//	电压
	printf(" F_AC_I_A = %.3f	A	\r\n" ,F_AC_I_A);						//	A通道电流
	printf(" F_AC_P_A = %.2f	W	\r\n" ,F_AC_P_A);						//	A通道功率
//	printf(" F_AC_P_SC = %.2f	W	\r\n " ,F_AC_P_SC);				//	视在功率
	printf(" F_AC_E_A = %f	KWH	\r\n " ,F_AC_E_A);				//	A通道电量
	printf("\r\n");//插入换行
}


/*=========================================================================================================
 * Function : void Calculate_HLW8110_MeterData(void);
 * Describe :
 * Input    : none
 * Output   : none
 * Return   : none
 * Record   : 2018/05/10
==========================================================================================================*/



void Calculate_HLW8110_MeterData(void)
{

	Read_HLW8110_U();
	Read_HLW8110_IA();
	Read_HLW8110_PA();
	Read_HLW8110_EA();

	Read_HLW8110_IB();
	Read_HLW8110_PB();
	Read_HLW8110_EB();




	printf("==============================================\r\n");
	printf("HLW8110/HLW8112-交流信号测量,uart通讯方式\r\n");
	printf("==============================================\r\n");
	printf("\r\n");//插入换行

	printf(" F_AC_V = %.2f	V	\r\n " ,F_AC_V);						//	电压
	printf(" F_AC_I_A = %.3f	A	\r\n" ,F_AC_I_A);						//	A通道电流
	printf(" F_AC_P_A = %.2f	W	\r\n" ,F_AC_P_A);						//	A通道功率
	printf(" F_AC_P_SC = %.2f	W	\r\n " ,F_AC_P_SC);				//	视在功率
	printf(" F_AC_E_A = %f	KWH	\r\n " ,F_AC_E_A);				//	A通道电量
	printf("\r\n");//插入换行


	printf(" F_AC_V = %.2f	\r\n " ,F_AC_V);					//	电压
	printf(" F_AC_I_B = %.3f	\r\n " ,F_AC_I_B);				//	B通道电流
	printf(" F_AC_P_B = %.2f	\r\n " ,F_AC_P_B);				//	B通道功率
	printf(" F_AC_E_B = %f	KWH	\r\n " ,F_AC_E_B);			//	B通道电量
	printf("\r\n");//插入换行

	printf(" F_AC_PF = %f \r\n " ,F_AC_PF);		//A通道功率因素
	printf(" F_AC_LINE_Freq = %f Hz \r\n " ,F_AC_LINE_Freq);		//F_AC_LINE_Freq
	printf(" F_Angle = %f \r\n  " ,F_Angle);
	printf("\r\n");//插入换行

	printf(" U32_RMSU_RegData = %lx \r\n 	" ,U32_RMSU_RegData);
	printf(" U32_RMSIA_RegData = %lx \r\n	" ,U32_RMSIA_RegData);
	printf(" U32_POWERPA_RegData = %lx \r\n 	" ,U32_POWERPA_RegData);
	printf(" U32_ENERGY_PA_RegData = %lx \r\n 	" ,U32_ENERGY_PA_RegData);
	printf("\r\n");//插入换行

	printf(" U32_RMSIB_RegData = %lx \r\n " ,U32_RMSIB_RegData);
	printf(" U32_POWERPB_RegData = %lx \r\n" ,U32_POWERPB_RegData);
	printf(" U32_ENERGY_PB_RegData = %lx \r\n " ,U32_ENERGY_PB_RegData);
	printf("\r\n");//插入换行

	printf(" U16_RMSUC_RegData = %x \r\n " ,U16_RMSUC_RegData);
	printf(" U16_RMSIAC_RegData = %x \r\n " ,U16_RMSIAC_RegData);
	printf(" U16_RMSIBC_RegData = %x \r\n " ,U16_RMSIBC_RegData);
	printf(" U16_PowerPAC_RegData = %x \r\n " ,U16_PowerPAC_RegData);
	printf(" U16_PowerPBC_RegData = %x \r\n " ,U16_PowerPBC_RegData);
	printf(" U16_EnergyAC_RegData = %x \r\n	 	" ,U16_EnergyAC_RegData);
	printf(" U16_EnergyBC_RegData = %x \r\n 	" ,U16_EnergyBC_RegData);
	printf(" U16_PowerSC_RegData = %x \r\n " ,U16_PowerSC_RegData);
	printf("\r\n");//插入换行

	printf(" SYSCON = %x \r\n " ,U16_Check_SysconReg_Data);
	printf(" EMUCON = %x	\r\n" ,U16_Check_EmuconReg_Data);
	printf(" EMUCON2 = %x	\r\n" ,U16_Check_Emucon2Reg_Data);
	printf("\r\n");//插入换行
	printf("\r\n");//插入换行

//	printf("==============================================\r\n");
}


#endif
